from robot.api import logger
from selenium.webdriver.common.by import By

from ..common.ui.PageElement import PageElement

from ..exception.TestException import TestException
from ..exception.errorcode import ErrorCode


class Select(PageElement):

    def setValue(self, *params):
        self.wait_element_presence()

        if len(params) <= 0:
            raise TestException.by_error_code(ErrorCode.PARAM_ERROR, message='Must set one value at least.')

        values = self._get_option_values(*params)
        if len(values) > 1:
            # 多选
            self._execute_script(f"$(arguments[0]).select('value', {values})", self._get_web_element())
        elif len(values) == 1:
            # 单选
            self._execute_script(f"$(arguments[0]).select('value', '{values[0]}')", self._get_web_element())

        selected_values = self.getValue()
        if values == list(selected_values):
            return

        logger.warn("call fish select method to set values failed, try the jquery method")
        # 如果前面方法没设置成功，使用jquery方法
        if len(values) > 1:
            # 多选
            self._execute_script(f"$(arguments[0]).val({values}).trigger('change')", self._get_web_element())
        elif len(values) == 1:
            # 单选
            self._execute_script(f"$(arguments[0]).val('{values[0]}').trigger('change')", self._get_web_element())

    def select(self, *params):
        return self.setValue(*params)

    def getValue(self):
        self.wait_element_presence()
        script = "return $(arguments[0]).val()"
        values = self._execute_script(script, self._get_web_element())
        return values

    def _get_option_values(self, *params):
        data_source = self._get_data_source()
        data_source_names = [data["name"] for data in data_source]
        data_source_values = [data["value"] for data in data_source]
        values = []
        for param in params:
            if param in data_source_names:
                name_index = data_source_names.index(param)
                value = data_source_values[name_index]
            elif param in data_source_values:
                value = param
            else:
                raise TestException.by_error_code(ErrorCode.COMBOBOX_VALUE_NOT_EXIST, value=param)
            values.append(value)
        return values


    def _get_data_source(self):
        # 方式1
        script = "return $(arguments[0]).select('option','dataSource');"
        try:
            results = self._execute_script(script, self._get_web_element())
            if results:
                return list(results)

            # 如果没有获取到值，用方式2去获取
        except Exception as e:
            logger.error("Get select data Source error:{0}\n Try another method..".format(str(e)))

        # 方式2
        options = self._get_web_element().find_elements(By.TAG_NAME, "option")
        if options:
            option_values =[]
            for option in options:
                title = self._execute_script("return $(arguments[0]).text();", option)
                value = option.get_attribute("value")
                option_values.append({"name": title, "value": value})
            return option_values
        else:
            raise TestException.by_error_code(ErrorCode.COMBOBOX_VALUE_NOT_EXIST, value="Not find dataSource")

    def get_identification(self):
        # identification = {'data-ui-role': ['select']}
        identification = {'tag': ['select']}
        return identification


